11. Use a Service Locator
L5 P3 A07 Use A Service Locator
In this step you'll refactor your main application code to use your ServiceLocator.
Step 1: Use ServiceLocator in Application
- At the top level of your package hierarchy, open
TodoApplicationand create avalfor your repository and assign it a repository that is obtained usingServiceLocator.provideTaskRepository:
TodoApplication.kt
class TodoApplication : Application() {
val taskRepository: TasksRepository
get() = ServiceLocator.provideTasksRepository(this)
override fun onCreate() {
super.onCreate()
if (BuildConfig.DEBUG) Timber.plant(DebugTree())
}
}
- Open
DefaultTasksRepositoryand delete the companion object:
DefaultTasksRepository.kt
// DELETE THIS COMPANION OBJECT
companion object {
@Volatile
private var INSTANCE: DefaultTasksRepository? = null
fun getRepository(app: Application): DefaultTasksRepository {
return INSTANCE ?: synchronized(this) {
val database = Room.databaseBuilder(app,
ToDoDatabase::class.java, "Tasks.db")
.build()
DefaultTasksRepository(TasksRemoteDataSource, TasksLocalDataSource(database.taskDao())).also {
INSTANCE = it
}
}
}
}
- Open
TaskDetailFragementand find the call togetRepositoryat the top of the class.
Replace this call with a call that gets the repository fromTodoApplication:
TaskDetailFragment.kt
// REPLACE this code
private val viewModel by viewModels<TaskDetailViewModel> {
TaskDetailViewModelFactory(DefaultTasksRepository.getRepository(requireActivity().application))
}
// WITH this code
private val viewModel by viewModels<TaskDetailViewModel> {
TaskDetailViewModelFactory((requireContext().applicationContext as TodoApplication).taskRepository)
}
- Do the same for
TasksFragment:
TasksFragment.kt
// REPLACE this code
private val viewModel by viewModels<TasksViewModel> {
TasksViewModelFactory(DefaultTasksRepository.getRepository(requireActivity().application))
}
// WITH this code
private val viewModel by viewModels<TasksViewModel> {
TasksViewModelFactory((requireContext().applicationContext as TodoApplication).taskRepository)
}
- For
StatisticsViewModelandAddEditTaskViewModelyou should update the code that acquires the repository to use the repository from theTodoApplicationas well:
TasksFragment.kt
// REPLACE this code
private val tasksRepository = DefaultTasksRepository.getRepository(application)
// WITH this code
private val tasksRepository = (application as TodoApplication).taskRepository
- Run your application (not the test)!
Since you only refactored, the app should run the same without issue.